package filefinder.finders;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Finder implementation using nio channels
 * 
 * @author denist
 * 
 */

public class ChannelGrepFinder extends GrepFinder {

	private final Charset charset = Charset.forName("ISO-8859-15");
	private final CharsetDecoder decoder = charset.newDecoder();

	public void find(File file, String toFind, List list) {
		FileChannel channel = null;
		FileInputStream fis = null;
		try {
			Matcher pm = null;
			Pattern pattern = compile(toFind);
			fis = new FileInputStream(file);
			channel = fis.getChannel();

			ByteBuffer bb = channel.map(MapMode.READ_ONLY, 0, channel.size());
			// CharBuffer cb = bb.asCharBuffer();
			CharBuffer cb = null;
			synchronized (decoder) {
				cb = decoder.decode(bb);
			}
			pm = pattern.matcher(cb);
			if (pm.find()) {
				synchronized (list) {
					list.add(file.getAbsolutePath());
				}
			}

		} catch (FileNotFoundException e) {
			System.out.println("Cannot open the file due to");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Cannot read the file due to");
			e.printStackTrace();
		} finally {
			if (channel != null) {
				try {
					channel.close();
				} catch (IOException e) {
					System.out.println("Cannot close the channel due to");
					e.printStackTrace();
				}
			}
		}
	}
}